package org.example.lethear.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.lethear.dto.comment.CommentCreateRequest;
import org.example.lethear.dto.comment.CommentDTO;
import org.example.lethear.dto.comment.CommentUpdateRequest;
import org.example.lethear.dto.common.PageResult;
import org.example.lethear.entity.Comment;
import org.example.lethear.entity.Post;
import org.example.lethear.entity.User;
import org.example.lethear.exception.BusinessException;
import org.example.lethear.exception.ForbiddenException;
import org.example.lethear.exception.ResourceNotFoundException;
import org.example.lethear.repository.CommentRepository;
import org.example.lethear.repository.PostRepository;
import org.example.lethear.repository.UserRepository;
import org.example.lethear.utils.SecurityUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 评论管理服务
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CommentService {
    
    private final CommentRepository commentRepository;
    private final PostRepository postRepository;
    private final UserRepository userRepository;
    
    /**
     * 创建评论
     */
    @Transactional
    public CommentDTO createComment(CommentCreateRequest request) {
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            throw new BusinessException("用户未登录");
        }
        
        // 检查帖子是否存在
        Post post = postRepository.findById(request.getPostId())
                .orElseThrow(() -> new ResourceNotFoundException("帖子不存在"));
        
        // 检查父评论是否存在（如果是回复）
        if (request.getParentId() != null) {
            Comment parentComment = commentRepository.findById(request.getParentId())
                    .orElseThrow(() -> new ResourceNotFoundException("父评论不存在"));
            
            // 检查父评论是否属于同一帖子
            if (!parentComment.getPostId().equals(request.getPostId())) {
                throw new BusinessException("父评论不属于当前帖子");
            }
        }
        
        // 检查回复的评论是否存在
        if (request.getReplyToId() != null) {
            Comment replyToComment = commentRepository.findById(request.getReplyToId())
                    .orElseThrow(() -> new ResourceNotFoundException("回复的评论不存在"));
            
            // 检查回复的评论是否属于同一帖子
            if (!replyToComment.getPostId().equals(request.getPostId())) {
                throw new BusinessException("回复的评论不属于当前帖子");
            }
        }
        
        // 创建评论
        Comment comment = new Comment();
        comment.setPostId(request.getPostId());
        comment.setUserId(currentUserId);
        comment.setContent(request.getContent());
        comment.setParentId(request.getParentId() != null ? request.getParentId() : 0L);
        comment.setLikeCount(0);
        comment.setStatus(1); // 正常状态
        
        comment = commentRepository.save(comment);
        
        // 增加帖子评论数
        post.incrementCommentCount();
        postRepository.save(post);
        
        log.info("评论创建成功: postId={}, commentId={}, userId={}", 
                request.getPostId(), comment.getId(), currentUserId);
        
        return convertToCommentDTO(comment);
    }
    
    /**
     * 更新评论
     */
    @Transactional
    public CommentDTO updateComment(Long commentId, CommentUpdateRequest request) {
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            throw new BusinessException("用户未登录");
        }
        
        Comment comment = commentRepository.findById(commentId)
                .orElseThrow(() -> new ResourceNotFoundException("评论不存在"));
        
        // 检查权限
        if (!comment.getUserId().equals(currentUserId) && !SecurityUtils.isAdmin()) {
            throw new ForbiddenException("无权限修改此评论");
        }
        
        // 更新内容
        if (StringUtils.hasText(request.getContent())) {
            comment.setContent(request.getContent());
        }
        
        comment = commentRepository.save(comment);
        
        log.info("评论更新成功: commentId={}, userId={}", commentId, currentUserId);
        
        return convertToCommentDTO(comment);
    }
    
    /**
     * 删除评论
     */
    @Transactional
    public void deleteComment(Long commentId) {
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            throw new BusinessException("用户未登录");
        }
        
        Comment comment = commentRepository.findById(commentId)
                .orElseThrow(() -> new ResourceNotFoundException("评论不存在"));
        
        // 检查权限
        if (!comment.getUserId().equals(currentUserId) && !SecurityUtils.isAdmin()) {
            throw new ForbiddenException("无权限删除此评论");
        }
        
        // 删除评论（软删除）
        comment.setStatus(0);
        commentRepository.save(comment);
        
        // 减少帖子评论数
        Post post = postRepository.findById(comment.getPostId())
                .orElseThrow(() -> new ResourceNotFoundException("帖子不存在"));
        post.decrementCommentCount();
        postRepository.save(post);
        
        log.info("评论删除成功: commentId={}, userId={}", commentId, currentUserId);
    }
    
    /**
     * 获取评论详情
     */
    public CommentDTO getCommentById(Long commentId) {
        Comment comment = commentRepository.findById(commentId)
                .orElseThrow(() -> new ResourceNotFoundException("评论不存在"));
        
        return convertToCommentDTO(comment);
    }
    
    /**
     * 获取帖子的评论列表
     */
    public PageResult<CommentDTO> getCommentsByPost(Long postId, int page, int size) {
        Pageable pageable = PageRequest.of(page - 1, size, Sort.by("createTime").ascending());
        
        // 只获取顶级评论（parentId为0）
        Page<Comment> commentPage = commentRepository.findTopLevelComments(postId, pageable);
        
        List<CommentDTO> commentDTOs = commentPage.getContent().stream()
                .map(this::convertToCommentDTO)
                .collect(Collectors.toList());
        
        return PageResult.of(commentDTOs, commentPage.getTotalElements(), page, size);
    }
    
    /**
     * 获取评论的回复列表
     */
    public PageResult<CommentDTO> getRepliesByComment(Long commentId, int page, int size) {
        Pageable pageable = PageRequest.of(page - 1, size, Sort.by("createTime").ascending());
        
        // 使用现有的方法获取回复，然后手动分页
        List<Comment> replies = commentRepository.findByParentIdAndStatus(commentId, 1);
        
        // 手动分页
        int start = Math.max(0, (page - 1) * size);
        int end = Math.min(replies.size(), start + size);
        List<Comment> paginatedReplies = replies.subList(start, end);
        
        List<CommentDTO> commentDTOs = paginatedReplies.stream()
                .map(this::convertToCommentDTO)
                .collect(Collectors.toList());
        
        return PageResult.of(commentDTOs, (long) replies.size(), page, size);
    }
    
    /**
     * 点赞评论
     */
    @Transactional
    public void likeComment(Long commentId) {
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            throw new BusinessException("用户未登录");
        }
        
        Comment comment = commentRepository.findById(commentId)
                .orElseThrow(() -> new ResourceNotFoundException("评论不存在"));
        
        // 简化：直接增加点赞数，不检查重复点赞
        comment.incrementLikeCount();
        commentRepository.save(comment);
        
        log.info("评论点赞成功: commentId={}, userId={}", commentId, currentUserId);
    }
    
    /**
     * 取消点赞评论
     */
    @Transactional
    public void unlikeComment(Long commentId) {
        Long currentUserId = SecurityUtils.getCurrentUserId();
        if (currentUserId == null) {
            throw new BusinessException("用户未登录");
        }
        
        Comment comment = commentRepository.findById(commentId)
                .orElseThrow(() -> new ResourceNotFoundException("评论不存在"));
        
        // 减少点赞数
        comment.decrementLikeCount();
        commentRepository.save(comment);
        
        log.info("取消评论点赞成功: commentId={}, userId={}", commentId, currentUserId);
    }
    
    /**
     * 转换Comment实体为CommentDTO
     */
    private CommentDTO convertToCommentDTO(Comment comment) {
        CommentDTO.CommentDTOBuilder builder = CommentDTO.builder()
                .id(comment.getId())
                .content(comment.getContent())
                .parentId(comment.getParentId() != 0 ? comment.getParentId() : null)
                .likeCount(comment.getLikeCount().longValue())
                .createdAt(comment.getCreateTime())
                .updatedAt(comment.getCreateTime()) // Comment实体只有createTime字段
                .isLiked(false); // 暂时设为false，后续实现点赞功能时再修改
        
        // 作者信息
        userRepository.findById(comment.getUserId()).ifPresent(user -> {
            CommentDTO.AuthorInfo authorInfo = CommentDTO.AuthorInfo.builder()
                    .id(user.getId())
                    .username(user.getUsername())
                    .nickname(user.getProfile() != null ? user.getProfile().getNickname() : null)
                    .avatar(user.getAvatar())
                    .build();
            builder.author(authorInfo);
        });
        
        // 帖子信息
        postRepository.findById(comment.getPostId()).ifPresent(post -> {
            User author = userRepository.findById(post.getUserId()).orElse(null);
            CommentDTO.PostInfo postInfo = CommentDTO.PostInfo.builder()
                    .id(post.getId())
                    .title(post.getTitle())
                    .authorId(post.getUserId())
                    .authorUsername(author != null ? author.getUsername() : null)
                    .build();
            builder.post(postInfo);
        });
        
        return builder.build();
    }
} 